/* dot1xSuppLib.h - 802.1X supplicant non-EAP specific library header file */

/* Copyright 2002-2004 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
modification history
--------------------
02q,05oct05,rb  Further fix to B0223
02p,04oct05,eja  Fix for trace bug B0223
02o,23sep05,eja  add state variable to SUPP_DEV_OBJ
02n,22sep05,eja  Major clean up on supplicant PAE data structure
02m,09sep05,eja  API change
02l,31aug05,eja  Add unicast key state variable to DOT1X_SUPP_PAE
02k,29aug05,eja  API change for dot1xSuppIdGet
02j,05aug05,eja  Version 2.1 update
02i,25jul05,eja  API change and cleanup
02h,06jul05,eja  Redefine supplicant state enumerations
02g,27jun05,eja  Cleanup
02f,02jun05,eja  Add statistics for physical port state and mac address
02e,30may05,eja  change default log size to 10 entries from 200
02d,12may05,eja  Add members for wep key stats
02c,10may05,eja  Add API dot1xSuppHandlerCacheInstall()
02b,09may05,eja  Change dot1xSuppShutdownAll() API
02a,04may05,eja  Add member to handler type to enable/disable eap type.
01z,20apr05,eja  Remove extra includes for Base6.1 RTP compliance
01y,11apr05,eja  Add new structure member
01x,24mar05,eja  Add debug event counters
01w,23mar05,eja  Add stats for debugging to PAE
01v,22mar05,eja  Add reset timer member to PAE
01u,22mar05,eja  Add reset flag member to PAE
01t,18mar05,eja  Moved EAP types to separate file and added logging
01s,01mar05,eja  Code cleanup
01r,18jan05,eja  Add 802.1X 2001 rev MIB statistics
01q,05jan05,eja  Add authWith element to DOT1X_SUPP_PAE
01p,21dec04,eja  Add public API prototype and make DOT1X_MODE type mirror BOOL.
01o,08dec04,eja  Fix trace bug B001
01n,07dec04,eja  Updated support
01m,19oct04,eja  Added support for multiple supplicants
01l,03dec03,dxb  Updated from code review
01k,21aug03,ggg  Add separate sign key in addition to session key
01j,05may03,ggg  Undefine debug macro by default
01i,30apr03,ss   added version info
01h,21apr03,ggg  File name, location change
01g,15apr03,ggg  Update copyright date
01f,15apr03,ggg  Further preparation for additional EAP types support
01e,08jul02,ggg  Undef debug by default
01d,08jul02,ggg  Update debug macro
01c,14jun02,ggg  Diab sensitivities
01b,11jun02,ggg  Add code review comments
01a,26mar02,ggg  written.
*/

#ifndef __INCdot1xSuppLibh
#define __INCdot1xSuppLibh

#ifdef __cplusplus
extern "C" {
#endif

#include <vxWorks.h>
#include <netinet/in.h>

/* supplicant version info */
#define DOT1X_SUPP_VERSION "2.1"
IMPORT char * dot1xSuppVersion;

/* Flag to indicate special conditions between "base" supplicant layer 
and the authentication protocol implementing a specific EAP method 
above it. */
#define DOT1X_SUPP_DESTROY (void*)(0xFFFFFFFF)  /* Shutdown and free */
#define DOT1X_SUPP_SUCCESS (void*)(0xFFFFFFFE)  /* authentication success */

/* Maximum sizes for username and password.  Must fit in a RADIUS 
attribute */
#define DOT1X_SUPP_MAX_USERNAME_LENGTH 256
#define DOT1X_SUPP_MAX_PASSWORD_LENGTH 256

/* Maxium sizes for session key.  Must fit in a RADIUS attribute */
#define DOT1X_SUPP_MAX_SESSION_KEY_LENGTH 256

/* Maximum sizes for name.  Must fit in a RADIUS attribute */
#define DOT1X_MAX_NAME_SIZE DOT1X_SUPP_MAX_USERNAME_LENGTH

/* Supplicant session/environment object */
typedef struct supp_env_s
    {
    void * ingress;       /* Incoming Packet */
    UINT32 ingressLen;    /* Incoming Packet length */
    void * egress;        /* Outgoing Packet */
    UINT32 egressLen;     /* Outgoing Packet length */
    char * uid;           /* User name */
    char * pwd;           /* Password */
    STATUS status;        /* Authentication status */
    INT32  authType;      /* Authentication type */
    INT32  innerAuthType; /* Inner Authentication type */
    void * tunnel;        /* ingress tunnel data */
    UINT32 tunnelLen;     /* ingress tunnel data size */
    void * private;       /* Private data */
    INT32  eapType;
    } SUPP_ENV_OBJ;

typedef STATUS (* SUPP_HANDLER_METHOD)();
typedef void * (* SUPP_EAP_HANDLER_METHOD)();
typedef void (* SUPP_DESTROY_METHOD)();
typedef void (* SUPP_SHOW_METHOD)();

/* Supplicant session object */
typedef struct 
    {
    SUPP_HANDLER_METHOD handler; /* Authentication handler */
    SUPP_DESTROY_METHOD destroy; /* Used to tear down session - EJA */
    SUPP_SHOW_METHOD    show;    /* Authenticator show routine */
    void *              session; /* Authentication session object */   
    char *              label;   /* Session Key label used by PRF */
    } SUPP_SESSION_OBJ;

/* Supplicant handler object */
typedef struct 
    {
    SUPP_EAP_HANDLER_METHOD routine; /* handler routine for this EAP type */
    int                     type;    /* identifier assigned to EAP type */
    SUPP_SHOW_METHOD        show;    /* show routine */
    SUPP_DESTROY_METHOD     destroy; /* destroy method */
    BOOL                    enabled; /* eap method enabled or disabled */
    int                     id;      /* supplicant numeric id */
    } DOT1X_SUPP_HANDLER;

/* Log defines */
#define DOT1X_LOG_FATAL "(f) " __FILE__ " (s) FATAL (r) "
#define DOT1X_LOG_ERROR "(f) " __FILE__ " (s) ERROR (r) "
#define DOT1X_LOG_INFO  "(f) " __FILE__ " (s) INFO  (r) "
#define DOT1X_LOG_DEBUG "(f) " __FILE__ " (s) DEBUG (r) "
#define DOT1X_LOG_ENTRY_SZ (100)
#define DOT1X_LOG_ENTRYS (10)

/* Supplicant State Machine states, IEEE 802.1X, 8.5.10 */
typedef enum
    {
    SUPP_DISCONNECTED = 1,
    SUPP_LOGOFF,
    SUPP_CONNECTING,
    SUPP_AUTHENTICATING,
    SUPP_AUTHENTICATED,
    SUPP_ACQUIRED,
    SUPP_HELD,
    SUPP_DOUBLY_AUTHENTICATED       
    } SUPP_STATE;

/* Enumeration to define mode of operation */
typedef enum 
    {
    DOT1X_MODE_WIRELINE = 0,/* Defines mode for wireline operation */
    DOT1X_MODE_WIRELESS /* Defines mode for wireless operation */
    } DOT1X_SUPP_MODE;

/* EAP handler and type node for singly linked list of them */
typedef struct dot1x_eap_handler_s
    {
    DOT1X_SUPP_HANDLER *         handler; /* EAP type handler */
    struct dot1x_eap_handler_s * next;    /* Node for list processing */
    } DOT1X_EAP_HANDLER;

#define MAC_ADDR_LEN (6)

/* 802.1X supplicant MIB statistics */
typedef struct dot1x_supp_stats_s
    {
    UINT32 portNumber;            /* Supplicants port number */
    UINT32 eapolFramesRxd;        /* EAPOL frames received */
    UINT32 eapolFramesTxd;        /* EAPOL frames transmitted */
    UINT32 eapolStartFramesTxd;   /* EAPOL start frames transmitted */
    UINT32 eapolLogoffFramesTxd;  /* EAPOL logoff frames transmitted */
    UINT32 eapolRespIdFramesTxd;  /* EAPOL RespId frames transmitted */
    UINT32 eapolRespFramesTxd;    /* EAPOL Response frames transmitted */
    UINT32 eapolReqIdFramesRxd;   /* EAPOL ReqId frames received */
    UINT32 eapolReqFramesRxd;     /* EAPOL Request frames received */
    UINT32 eapolInvalidFramesRxd; /* EAPOL invalid frames received */
    UINT32 eapolLenErrFramesRxd;  /* EAPOL length error frames received */
    UINT32 eapolLastFrameVerRxd;  /* EAPOL last frame version received */
    char eapolLastFrameSrcRxd[MAC_ADDR_LEN]; /* EAPOL last frame source */
    } SUPP_MIB_STATS_OBJ;

/* Supplicant runtime statistics */
typedef struct
    {
    UINT32 sessionFailures;
    UINT32 sessionStarts;
    UINT32 sessionSuccess;
    UINT32 associationEvents;
    UINT32 disassociationEvents;
    UINT32 aEvents;
    UINT32 dEvents;
    UINT32 rejectedEvents;
    UINT32 wep40Keys;
    UINT32 wep104Keys;
    UINT32 physLayerPortState;
    UINT32 averageAuthTime;
    char   physLayerPortMacAddr[MAC_ADDR_LEN];
    } SUPP_RUNTIME_STATS_OBJ;

/* Supplicant statistics */
typedef struct
    {
    SUPP_MIB_STATS_OBJ     mib;     /* MIB stats */
    SUPP_RUNTIME_STATS_OBJ runtime; /* Runtime stats */
    } SUPP_STATS_OBJ;

/* Supplicant Variables, IEEE 802.1X, 8.5.10.1.1 */
typedef struct 
    {
    SUPP_STATE  state;      /* State of the Machine */
    BOOL        userLogoff; /* Is user logged off? */
    BOOL        logoffSent; /* Has logoff message been sent? */
    BOOL        reqId;      /* Got EAP-Request/Identity? */
    BOOL        reqAuth;    /* Got EAP-Request not Identity? */
    BOOL        eapSuccess; /* Got EAP-Success? */
    BOOL        eapFail;    /* Got EAP-Failure? */
    INT32       startCount; /* How many EAPOL-Starts sent */
    INT32       previousId; /* Last request ID responded to */
    BOOL        receivedId; /* Request ID most recently received */
    BOOL        resetFlag;
    } SUPP_SESS_OBJ;

/* Timer Variables, IEEE 802.1X, 8.5.2.1 */
typedef struct 
    {
    INT32 authWhile; /* When to time out on Auth. resp. */
    INT32 heldWhile; /* How long to wait before acquiring */
    INT32 startWhen; /* When to send EAPOL-Start */
    INT32 resetTimer;
    } SUPP_TMR_OBJ;

/* "Global" (used by more than one SM) Variables, IEEE 802.1X, 8.5.2.2 */
typedef struct 
    {
    BOOL  init;           /* Forces all state machines to init */
    BOOL  enabled;        /* Is the MAC for the port up? */
    BOOL  status;         /* Authorized or Unauthorized */
    INT32 mode;           /* Mode of operation */
    int   id;             /* Device ID */
    BOOL  trace;          /* Packet trace enabled */
    BOOL  unicastKeySet;  /* Unicast key set */ 
    int   nextHandlerSel; /* Next handler to try */
    } SUPP_DEV_OBJ;

/* Supplicant Constants, IEEE 802.1X, 8.5.10.1.2 */
typedef struct 
    {
    INT32 authPeriod;  /* in secs, authWhile timer init value */
    INT32 heldPeriod;  /* in secs, heldWhile timer init value */
    INT32 startPeriod; /* in secs, startWhen timer init value */
    INT32 maxStart;    /* max # of EAPOL-Start messages */
    } SUPP_CFG_OBJ;

/* Certificate names and location */
typedef struct
    {
    char  certDir[DOT1X_MAX_NAME_SIZE + 1];
    char  keyFile[DOT1X_MAX_NAME_SIZE + 1];
    char  keyPassword[DOT1X_SUPP_MAX_PASSWORD_LENGTH + 1];
    char  caCertFile[DOT1X_MAX_NAME_SIZE + 1];
    char  caCertPath[DOT1X_MAX_NAME_SIZE + 1];
    char  randFile[DOT1X_MAX_NAME_SIZE + 1];
    char  certFile[DOT1X_MAX_NAME_SIZE + 1];
    INT32 currentTime;
    } SUPP_SSL_OBJ;

/* Supplicant data logging */
typedef struct
    {
    void   (*pEvent)();
    UINT32 entries;
    UINT32 currEntry;
    char   entry[DOT1X_LOG_ENTRYS][DOT1X_LOG_ENTRY_SZ];
    } SUPP_LOG_OBJ;

/* Supplicant session key info */
typedef struct
    {
    char * pSign;       /* Signature key */
    char   session[DOT1X_SUPP_MAX_SESSION_KEY_LENGTH]; /* Session key */
    INT32  sessionSize; /* Session key size in bytes */
    INT32  signSize;    /* Signature key size in bytes */
    } SUPP_KEY_OBJ;

/* Supplicant interface binding */
typedef struct
    {
    void * pCookie;                        /* EAPOL on the port */
    char   name[DOT1X_MAX_NAME_SIZE + 1]; /* Device name */
    INT32  unit;                          /* interface unit number */
    } SUPP_EAPOL_OBJ;

/* EAP */
typedef struct
    {
    DOT1X_EAP_HANDLER *  pList;       /* Supported handler list */
    DOT1X_SUPP_HANDLER * pNegotiated; /* Default handler */
    void *               pPhase1;     /* outer auth specific handler */
    void *               pPhase2;     /* inner auth specific handler */
    INT32                phase1;      /* Last method used for phase1 */
    INT32                phase2;      /* Last method used for phase2 */
    } SUPP_EAP_OBJ;

/* Supplicant authentication info  */
typedef struct
    {
    char *        pResp; /* Response from authentication handler */
    char          macAddr[MAC_ADDR_LEN]; /* MAC address of authenticator */
    char          user[DOT1X_SUPP_MAX_USERNAME_LENGTH]; /* username */
    char          password[DOT1X_SUPP_MAX_PASSWORD_LENGTH]; /* password */
    SUPP_EAP_OBJ  eap; 
    } SUPP_AUTH_OBJ;

/* Supplicant interval variables */
typedef struct 
    {
    SUPP_SESS_OBJ  sess;  /* Session parameters */
    SUPP_TMR_OBJ   tmr;   /* Timer parameters */
    SUPP_DEV_OBJ   dev;   /* Global parameters - override locals */
    SUPP_CFG_OBJ   cfg;   /* Configuration parameters */
    SUPP_EAPOL_OBJ eapol; /* Network interface info */
    SUPP_AUTH_OBJ  auth;  /* Authentication info */
    SUPP_SSL_OBJ   ssl;   /* Certificate info */
    SUPP_KEY_OBJ   key;   /* Key info */
    SUPP_LOG_OBJ   log;   /* Log info */
    SUPP_STATS_OBJ stats; /* Stats */
    } SUPP_OBJ;

/* PAE for supplicant */
typedef struct supplicant_s
    {
    SUPP_OBJ              obj;  /* Supplicant object */
    struct supplicant_s * next; /* Next supplicant in the list */
    } DOT1X_SUPP_PAE;

/* Public APIs */

/* Create root task - Kernel mode */
STATUS dot1xSuppLibInit(void *);
/* Display Supplcant Info - Kernel mode */
STATUS dot1xSuppShow(BOOL);
/* Create and add a supplicant to the root task list - Kernel/User mode */
int dot1xSuppCreate(int, char *, int);
/* Destroy and delete a supplicant from root task list - Kernel/User mode */
STATUS dot1xSuppDelete(int);
/* Bind an authentication handler to a supplicant - Kernel mode */
STATUS dot1xSuppHandlerAdd(int, void *);
/* Unbind an authentication handler from a supplicant - Kernel mode */
STATUS dot1xSuppHandlerRemove(int, void *);
/* Set the username and password for a supplicant - Kernel/User mode */
STATUS dot1xSuppLogonSet(int, char *, char *);
/* Get the username and password for a supplicant - Kernel/User mode */
STATUS dot1xSuppLogonGet(int, char *, char *);
/* Set information used by cert based authentication - Kernel/User mode */
STATUS dot1xSuppCertInfoSet(int, char *, char *, char *, char *, char *, 
                            char *);
/* Get information used by cert based authentication - Kernel/User mode */
STATUS dot1xSuppCertInfoGet(int, char *, char *, char *, char *, char *, 
                            char *);
/* Enable or Disable packet trace - Kernel/User mode */
BOOL dot1xSuppPacketTrace(int, BOOL);
/* Flush supplicant event log - Kernel/User mode */
STATUS dot1xSuppEventLogFlush(int);
/* Display contents of supplicant datalog - - Kernel mode */
void dot1xSuppEventLogShow(int);
/* Get supplicant ID based on instance number - Kernel/User mode */
int dot1xSuppIdGet(char *, int);
/* Force supplicant to connect to NAS - Kernel/User mode */
STATUS dot1xSuppConnect(int);
/* Shutdown all supplicants and delete all tasks - Kernel mode */
STATUS dot1xSuppShutdownAll(void);
/* Enable EAP method - Kernel/User mode */
STATUS dot1xSuppEapTypeEnable(int, void *);
/* Disable EAP method - Kernel/User mode */
STATUS dot1xSuppEapTypeDisable(int, void *);
STATUS dot1xSuppHandlerCacheInstall(int);
/* Validate EAP type */
STATUS dot1xSuppPhase2HandlerValidate(void *, int, int *, int);
int dot1xSuppPhase2HandlerFind(void *, int);
/* utility function */
char dot1xSuppReceivedPktIdGet(void *);
void dot1xSuppResponsePktIdSet(void *, char);
STATUS dot1xSuppCertStoreValidate(void *);
#ifdef __cplusplus
}
#endif

#endif /* __INCdot1xSuppLibh */
